package com.qiaofang.applet.service.other.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.qiaofang.applet.common.base.MongoBaseService;
import com.qiaofang.applet.constants.CountSynConstants;
import com.qiaofang.applet.service.other.domain.SynchronousData;
import com.qiaofang.applet.service.other.repository.SynchronousDataRepository;
import com.qiaofang.applet.service.other.service.SynchronousDataService;
import com.qiaofang.applet.service.other.service.dto.CountFirstPullDto;
import com.qiaofang.applet.service.other.service.dto.CountSynDataDto;
import com.qiaofang.applet.service.other.util.DateTypeUtil;
import com.qiaofang.applet.service.property.service.DataProcessingErrorLogService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;

import java.util.Calendar;
import java.util.Date;

/**
 * @Author: youqing.yang
 * @Create: 2020/11/09 14:55
 * @Description:
 **/
@Service
@Slf4j
public class SynchronousDataServiceImpl extends MongoBaseService<SynchronousData, String> implements SynchronousDataService {

    private final SynchronousDataRepository synchronousDataRepository;

    @Autowired
    MongoTemplate mongoTemplate;

    @Autowired
    DataProcessingErrorLogService dataProcessingErrorLogService;

    @Autowired
    public SynchronousDataServiceImpl(SynchronousDataRepository repository) {
        super(repository);
        this.synchronousDataRepository = repository;
    }

    @Override
    public void updateSynData(SynchronousData synchronousData) {
        updateById(synchronousData);
    }

    @Override
    public void deleteDataToWeek(String corporationCode, String companyUuid) {
        //获取当前时间
        Date newDate = new Date();
        Date beginDate = DateTypeUtil.getBeginOrAfterDay(newDate, Calendar.DAY_OF_WEEK, -7);
        Query query = new Query();
        Criteria criteria = Criteria.where("corporationCode").is(corporationCode);
        criteria.and("companyUuid").is(companyUuid);
        criteria.and("createTime").lte(beginDate);
        query.addCriteria(criteria);
        mongoTemplate.remove(query, SynchronousData.class);
    }

    @Override
    public long countInsertOrUpdate(CountSynDataDto countSynDataDto) {
        long count = 0;
        try {
            Query query = new Query();
            Criteria criteria = Criteria.where("corporationCode").is(countSynDataDto.getCorporationCode());
            criteria.and("companyUuid").is(countSynDataDto.getCompanyUuid());
            criteria.and("cityCode").is(countSynDataDto.getCityCode());
            criteria.and("lastSyncDate").gte(countSynDataDto.getUpdateTime());
            query.addCriteria(criteria);
            String collectionName = CountSynConstants.getCollectionNameByType(countSynDataDto.getSynchronousType());
            if (StringUtils.isNotBlank(collectionName)) {
                count = mongoTemplate.count(query, collectionName);
            }
        } catch (Exception e) {
            log.error("统计更新成功数据异常 {}", e);
        }
        return count;
    }

    @Override
    public void countFirstPullNum(CountFirstPullDto countFirstPullDto) {
        SynchronousData synchronousData = new SynchronousData();
        BeanUtils.copyProperties(countFirstPullDto, synchronousData);
        synchronousData.setStartData(new Date());
        log.info("每天同步数据开始统计数量：{}, 集团: {}, 公司：{}, 类型:{}", synchronousData.getPullCount()
                , synchronousData.getCorporationCode(), synchronousData.getCompanyUuid(), synchronousData.getSynchronousType());
        try {
            synchronousDataRepository.save(synchronousData);
        } catch (Exception e) {
            log.error("统计小程序拉取数量失败：", e);
        }
    }

    @Override
    public void refreshSynCount(CountSynDataDto countSynDataDto) {
        Query query = new Query();
        Criteria criteria = Criteria.where("corporationCode").is(countSynDataDto.getCorporationCode());
        criteria.and("companyUuid").is(countSynDataDto.getCompanyUuid());
        criteria.and("cityCode").is(countSynDataDto.getCityCode());
        criteria.and("lastSyncDate").gte(countSynDataDto.getUpdateTime());
        query.addCriteria(criteria);
        String collectionName = CountSynConstants.getCollectionNameByType(countSynDataDto.getSynchronousType());
        if (StringUtils.isBlank(collectionName)) {
            log.info("查询解析对象为空：{}, 入参：{}", collectionName, JSONObject.toJSONString(countSynDataDto));
            return;
        }
        //解析（每日增量）数量
        long resolveCount = mongoTemplate.count(query, collectionName);
        //解析失败数量
        long resolveFailCount = dataProcessingErrorLogService.resolveDataErrorCount(countSynDataDto);
        SynchronousData synchronousData = getLastedData(countSynDataDto);

        if (synchronousData == null) {
            return;
        }
        synchronousData.setResolveCount((int) resolveCount);
        synchronousData.setResolveFailCount((int)resolveFailCount);
        synchronousData.setPullFailCount(synchronousData.getPullCount()
                - synchronousData.getResolveCount() - synchronousData.getResolveFailCount());
        updateById(synchronousData);
    }

    private SynchronousData getLastedData(CountSynDataDto countSynDataDto) {
        Query query = new Query();
        Criteria criteria = Criteria.where("corporationCode").is(countSynDataDto.getCorporationCode());
        criteria.and("companyUuid").is(countSynDataDto.getCompanyUuid());
        criteria.and("cityCode").is(countSynDataDto.getCityCode());
        criteria.and("startData").gte(countSynDataDto.getUpdateTime());
        criteria.and("synchronousType").is(countSynDataDto.getSynchronousType());
        query.addCriteria(criteria);
        query.with(Sort.by(Sort.Order.desc("startData")));
        SynchronousData synchronousData = mongoTemplate.findOne(query, SynchronousData.class);
        log.info("获取当日开始拉取数量记录：{}", JSONObject.toJSONString(synchronousData));
        return synchronousData;
    }
}
